package com.example.demo.config.artemis;

import org.apache.activemq.artemis.core.config.impl.SecurityConfiguration;
import org.apache.activemq.artemis.core.server.embedded.EmbeddedActiveMQ;
import org.apache.activemq.artemis.jms.client.ActiveMQConnectionFactory;
import org.apache.activemq.artemis.spi.core.security.ActiveMQJAASSecurityManager;
import org.apache.activemq.artemis.spi.core.security.jaas.InVMLoginModule;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jms.config.DefaultJmsListenerContainerFactory;
import org.springframework.jms.config.JmsListenerContainerFactory;
import org.springframework.jms.connection.CachingConnectionFactory;
import org.springframework.jms.core.JmsTemplate;

import javax.annotation.PreDestroy;
import javax.jms.ConnectionFactory;
import javax.jms.Session;

@Configuration
public class ArtemisMqConfig {
    public static final String PROTO_VM = "vm://0";
    public static final String PROTO_TCP = "tcp://127.0.0.1:61616";

    private static final Logger logger = LoggerFactory.getLogger(ArtemisMqConfig.class);
    @Autowired
    ConnectionFactory connectionFactory;

    @Bean
    public ConnectionFactory connectionFactory() {
        try {
            ActiveMQConnectionFactory mqConnectionFactory = new ActiveMQConnectionFactory(PROTO_TCP, "admin", "123");
            mqConnectionFactory.setPreAcknowledge(true);
            mqConnectionFactory.setClientID("demo-service");
            CachingConnectionFactory factory = new CachingConnectionFactory(mqConnectionFactory);
            return factory;
        } catch (Exception e) {
            logger.error("Failed to create client connection factory, reason: {}.", e.getMessage());
        }


        return null;
    }

    @PreDestroy//
    public void destroy() {
        if(connectionFactory != null) {
            CachingConnectionFactory factory = (CachingConnectionFactory) connectionFactory;
            factory.destroy();
            factory.setTargetConnectionFactory(null);
        }

    }

    @Bean
    public JmsTemplate jmsTemplate(ConnectionFactory connectionFactory) {
        JmsTemplate template = new JmsTemplate(connectionFactory);
        template.setSessionAcknowledgeMode(Session.AUTO_ACKNOWLEDGE);
        return template;
    }

    @Bean
    public JmsListenerContainerFactory jmsListenerContainerFactory(ConnectionFactory connectionFactory) {
        DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory();
        //SimpleJmsListenerContainerFactory factory = new SimpleJmsListenerContainerFactory();
        factory.setConnectionFactory(connectionFactory);
        factory.setSessionAcknowledgeMode(Session.AUTO_ACKNOWLEDGE);
        return factory;
    }

    //@Bean
    public ActiveMQJAASSecurityManager securityManager() {
        final SecurityConfiguration configuration = new SecurityConfiguration();
        final ActiveMQJAASSecurityManager securityManager =
                new ActiveMQJAASSecurityManager(InVMLoginModule.class.getName(), configuration);
        configuration.addUser("admin", "123");
        configuration.addRole("admin", "admin");
        configuration.setDefaultUser("admin");

        return securityManager;
    }

    //@Bean(initMethod = "start", destroyMethod = "stop")
    public EmbeddedActiveMQ embeddedActiveMQ(ActiveMQJAASSecurityManager securityManager) {
        final EmbeddedActiveMQ embeddedActiveMQ = new EmbeddedActiveMQ();
        embeddedActiveMQ.setSecurityManager(securityManager);
        return embeddedActiveMQ;
    }
}
